import { Button, VerticalBox , HorizontalBox, TabWidget, ListView, StandardListView, StandardTableView, CheckBox, ScrollView} from "std-widgets.slint";
import {TypeOfOpenedItem} from "common.slint";
import {ColorPalette} from "color_palette.slint";
import {MainListModel} from "common.slint";
import {Callabler} from "callabler.slint";
import {GuiState} from "gui_state.slint";

export component SelectableTableView inherits Rectangle {
    callback item_opened(string);
    in property <[string]> columns;
    in-out property <[MainListModel]> values: [
        {checked: false, selected_row: false, header_row: true, filled_header_row: false, val_str: ["kropkarz", "/Xd1", "24.10.2023"], val_int: []} ,
        {checked: false, selected_row: false, header_row: false, filled_header_row: false, val_str: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"], val_int: []} ,
        {checked: false, selected_row: false, header_row: false, filled_header_row: false, val_str: ["witasphere", "/Xd1/Imagerren2", "25.11.1991"], val_int: []} ,
        {checked: true, selected_row: false, header_row: false, filled_header_row: false, val_str: ["lokkaler", "/Xd1/Vide2", "01.23.1911"], val_int: []}
    ];
    in-out property <[length]> column_sizes: [30px, 80px, 150px, 160px];
    private property <int> column_number: column_sizes.length + 1;
    // This idx, starts from zero, but since first is always a checkbox, and is not in model.val values, remove 1 from idx
    in-out property <int> parentPathIdx;
    in-out property <int> fileNameIdx;
    in-out property <int> selected_item: -1;
    out property <length> list_view_width: max(self.width - 20px, column_sizes[0] + column_sizes[1] + column_sizes[2] + column_sizes[3] + column_sizes[4] + column_sizes[5] + column_sizes[6] + column_sizes[7] + column_sizes[8] + column_sizes[9] + column_sizes[10] + column_sizes[11]);

    VerticalBox {
        padding: 0px;
        ScrollView {
            height: 30px;
            viewport-x <=> list_view.viewport-x;
            vertical-stretch: 0;

            HorizontalLayout {
                spacing: 5px;
                for title [idx] in root.columns: HorizontalLayout {
                    width: root.column_sizes[idx];
                    Text {
                        overflow: elide;
                        text: title;
                    }

                    Rectangle {
                        width: 1px;
                        background: gray;
                        TouchArea {
                            width: 8px;
                            x: (parent.width - self.width) / 2;
                            property <length> cached;
                            pointer-event(event) => {
                                if (event.button == PointerEventButton.left && event.kind == PointerEventKind.down) {
                                    self.cached = root.column_sizes[idx];
                                }
                            }
                            moved => {
                                if (self.pressed) {
                                    root.column_sizes[idx] += (self.mouse-x - self.pressed-x);
                                    if (root.column_sizes[idx] < 20px) {
                                        root.column_sizes[idx] = 20px;
                                    }
                                }
                            }
                            mouse-cursor: ew-resize;
                        }
                    }
                }
            }
        }

        list_view := ListView {
            padding: 0px;
            min-width: 100px;
            for r [idx] in root.values: Rectangle {
                width: list_view_width;
            
                border-radius: 5px;
                height: 20px;
                background: ColorPalette.get_listview_color_with_header(r.selected_row, touch-area.has-hover, r.header_row);
                touch_area := TouchArea {
                    function clicked_manual() {
                        // We don't allow to select header row
                        // unless it contains data, which is true only for for modes with reference folders
                        if (!r.header_row || r.val_str.length > 0) {
                            if (root.selected_item == -1) {
                                r.selected_row = !r.selected_row;
                                root.selected_item = idx;
                            } else {
                                if (!r.selected_row && root.selected_item != idx) {
                                    r.selected_row = !r.selected_row;
                                    root.values[root.selected_item].selected_row = false;
                                    root.selected_item = idx;
                                }
                            }

                            if (root.selected_item != -1) {
                                showPreview();
                            } else {
                                GuiState.preview_visible = false;
                            }
                        }
                    }
                    double-clicked => {
                        if (r.header_row && !r.filled_header_row) {
                            return;
                        }
                        openSelectedItem();
                    }
                    pointer-event(event) => {
                        // TODO this should be clicked by double-click - https://github.com/slint-ui/slint/issues/4235
                        if (event.button == PointerEventButton.right && event.kind == PointerEventKind.up) {
                            if (r.header_row && !r.filled_header_row) {
                                return;
                            }
                            Callabler.item_opened(r.val_str[root.parentPathIdx - 1])
                        } else if (event.button == PointerEventButton.left && event.kind == PointerEventKind.up) {
                            clicked_manual();
                        }
                        //else if (event.button == PointerEventButton.middle && event.kind == PointerEventKind.up) {
                        //    Callabler.item_opened(r.val_str[root.parentPathIdx - 1] + "/" + r.val_str[root.fileNameIdx - 1])
                        //}
                    }
                }

                HorizontalLayout {
                    CheckBox {
                        visible: !r.header_row;
                        checked: r.checked && !r.header_row;
                        width: root.column_sizes[0];
                        toggled => {
                            r.checked = self.checked;
                        }
                    }

                    HorizontalLayout {
                        spacing: 5px;
                        for f [idx] in r.val_str: Text {
                            width: root.column_sizes[idx + 1];
                            text: f;
                            font-size: 12px;
                            vertical-alignment: center;
                            overflow: elide;
                        }
                    }
                }
            }
        }
    }

    public function deselect_selected_item() {
        if (root.selected_item != -1) {
            root.values[root.selected_item].selected_row = false;
            root.selected_item = -1;
        }
    }

    function showPreview() {
        Callabler.load_image_preview(root.values[root.selected_item].val_str[root.parentPathIdx - 1] + "/" + root.values[root.selected_item].val_str[root.fileNameIdx - 1]);
    }

    function openSelectedItem() {
        Callabler.item_opened(root.values[root.selected_item].val_str[root.parentPathIdx - 1] + "/" + root.values[root.selected_item].val_str[root.fileNameIdx - 1]);
    }

    // TODO this should work with multiple selection and shift and control key - problably logic will need to be set in global state
    public function released_key(event: KeyEvent) {
        if (event.text == " ") {
            if (root.selected_item != -1 && !root.values[root.selected_item].header_row) {
                root.values[root.selected_item].checked = !root.values[root.selected_item].checked;
            }
        } else if (event.text == "\n" ) {
            if (root.selected_item != -1) {
                openSelectedItem();
            }
        } else if (event.text == Key.DownArrow) {
            if (root.selected_item != -1) {
                if (root.values.length - 1 == root.selected_item) {
                    // Last element, so unselect it
                    root.values[root.selected_item].selected_row = false;
                    root.selected_item = -1;
                } else {
                    // Select next item, if next item is header row, then select second
                    // This should be safe, because header row should never be last item
                    root.values[root.selected_item].selected_row = false;
                    if (root.values[root.selected_item + 1].header_row) {
                        root.selected_item += 2;
                    } else {
                        root.selected_item += 1;
                    }
                    root.values[root.selected_item].selected_row = true;
                    showPreview();
                }
            } else {
                // Select last item if nothing is selected
                if (root.values.length > 0) {
                    if (root.values[0].header_row) {
                        root.selected_item = 1;
                    } else {
                        root.selected_item = 0;
                    }
                    root.values[root.selected_item].selected_row = true;
                    showPreview();
                }
            }
        } else if (event.text == Key.UpArrow) {
            if (root.selected_item != -1) {
                if (root.selected_item == 0) {
                    // First element, so unselect it
                    root.values[root.selected_item].selected_row = false;
                    root.selected_item = -1;
                } else {
                    root.values[root.selected_item].selected_row = false;
                    // Select previous item, if previous item is header row, then select second previous item
                    // This is safe, because if there is non header row upper, then can be easily selected,
                    // but otherwise is done -2 which for 1 (smallest possible item to set with header row) gives -1, so gives
                    // this non selected row
                    if (root.values[root.selected_item - 1].header_row) {
                        root.selected_item -= 2;
                    } else {
                        root.selected_item -= 1;
                    }
                    if (root.selected_item != -1) {
                        root.values[root.selected_item].selected_row = true;
                        showPreview();
                    }
                }
            } else {
                // Select last item if nothing is selected
                if (root.values.length > 0) {
                    root.selected_item = root.values.length - 1;
                    root.values[root.selected_item].selected_row = true;
                    showPreview();
                }
            }
        }
    }
}
